package com.gitee.feizns.quickstart.dict.spring.boot.autoconfigure.db.mybatis.plus;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.gitee.feizns.dynamic.bean.Beans;
import com.gitee.feizns.dynamic.reflect.Lambdas;
import com.gitee.feizns.quickstart.dict.AbstractDictDepositor;
import com.gitee.feizns.quickstart.dict.DictDepositor;
import com.gitee.feizns.quickstart.dict.Entry;
import com.gitee.feizns.quickstart.dict.NothingToDoDictDepositor;
import com.gitee.feizns.quickstart.dict.Permission;
import com.gitee.feizns.quickstart.mybatis.plus.utils.Mappers;

import java.util.List;

/**
 * qk dict 存款器
 * @author feizns
 * @since 2024/12/20
 */
public class MybatisPlusQkDepositor<T extends Entry> extends AbstractDictDepositor<T> {

    /**
     * 入门类
     */
    private final Class<T> entityClass;

    /**
     * 键名称
     */
    private final SFunction<T, ?> keyFunc;

    /**
     * 映射
     */
    private final BaseMapper<T> mapper;

    /**
     * mybatis plus QK 存款器
     * @param keyFunc 关键功能
     */
    public MybatisPlusQkDepositor(SFunction<T, ?> keyFunc) {
        this(keyFunc, new NothingToDoDictDepositor<>());
    }

    /**
     * mybatis plus QK 存款器
     * @param keyFunc 关键功能
     * @param delegate 委托
     */
    public MybatisPlusQkDepositor(SFunction<T, ?> keyFunc, DictDepositor<T> delegate) {
        super(delegate);
        this.keyFunc = keyFunc;
        this.entityClass = Lambdas.ofClass(keyFunc);
        this.mapper = Mappers.of(entityClass);
    }

    @Override
    public DictDepositor<T> reload() {
        if ( delegate != null )
            delegate.reload();
        return this;
    }

    @Override
    public List<T> list() {
        return Mappers.of(entityClass).selectList(Wrappers.query());
    }

    @Override
    public T get(String key) {
        //查询数据库是否存在
        T entry = mapper.selectOne(Wrappers.<T>query().lambda().eq(keyFunc, key));
        //放置缓存
        if ( entry == null ) {
            //代理查找
            entry = delegate.get(key);
            //
            if ( entry != null ) {
                T one = Beans.copyProperties(entityClass, entry);
                mapper.insert(one);
            }
        }
        return entry;
    }

    @Override
    public void put(T entry) {
        T one = mapper.selectOne(Wrappers.<T>query().lambda().eq(keyFunc, entry.getKey()));
        if ( one != null && one.getPermission() == Permission.ReadOnly )
            throw new UnsupportedOperationException(String.format("不支持修改只读字典[%s]", one.getKey()));
        if ( one == null ) {
            one = Beans.copyProperties(entityClass, entry);
            mapper.insert(one);
        } else {
            Beans.copyProperties(one, entry);
            mapper.updateById(one);
        }
        //处理代理
        delegate.put(entry);
    }

    @Override
    public boolean exists(String key) {
        return mapper.exists(Wrappers.<T>query().lambda().eq(keyFunc, key));
    }

    @Override
    public T delete(String key) {
        T entry = get(key);
        if ( entry != null ) {
            if ( entry.getPermission() == Permission.ReadOnly )
                throw new UnsupportedOperationException(String.format("不支持删除只读字典[%s]", entry.getKey()));
            mapper.delete(Wrappers.<T>query().lambda().eq(keyFunc, key));
            delegate.delete(key);
        }
        return entry;
    }

}
